package org.example.cicdi.service.impl.third.fieldcondition;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.example.cicdi.oConvertUtils;
import org.example.cicdi.service.impl.second.AnnotationUtil;
import org.example.codegenerate.modelext.WebVo.Enum.EnumJavaMappingDbType;
import org.example.codegenerate.modelext.WebVo.Enum.EnumTableType;
import org.example.codegenerate.modelext.WebVo.domian.column.ColumnVoDomain;
import org.example.codegenerate.modelext.WebVo.domian.column.DbVo;
import org.example.codegenerate.modelext.WebVo.domian.table.TableVoDomain;
import org.example.codegenerate.modelext.WebVo.domian.table.WebModelVo;
import org.springframework.stereotype.Component;

import javax.persistence.*;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Optional;
@Slf4j
@Component
public class NoColumnHasManyToOneHasJoinColumn extends AbstractColumnAndManyToOne{
    public NoColumnHasManyToOneHasJoinColumn(){
        localfieldCondition.setHasorNotJoinColumn(EnumConsantExistFieldType.HasJoinColumn.getStatus());
        localfieldCondition.setHasorNotJpaManyToOne(EnumConsantExistFieldType.HasManyToOne.getStatus());
        localfieldCondition.setHasorNotColumn(EnumConsantExistFieldType.NoColumn.getStatus());
    }
    @Override
    protected void execute(Field field, ColumnVoDomain column, WebModelVo webModelVo, List<WebModelVo> webModelVoList) {
        TableVoDomain tableVoDomain=webModelVo.getTableVoDomain();
                //处理本身的内容
                DbVo db = column.getDbVo();

                //获取关联的表
                Class<?>fClass = field.getType();
                WebModelVo wvo=new WebModelVo();
                String assocationTablename="";
                if(fClass.getAnnotation(Table.class)!=null) {
                    assocationTablename=fClass.getAnnotation(Table.class).name();
                }else {
                    assocationTablename = oConvertUtils.camelToUnderline(fClass.getName());
                }
                    String finalAssocationTablename = assocationTablename;
                    Optional<WebModelVo> opwvo=webModelVoList.stream()
                            .filter(x->x.getTableVoDomain().getTableName().equalsIgnoreCase(finalAssocationTablename))
                            .findFirst();
                if(opwvo.isPresent()){
                    wvo=opwvo.get();
                }else {
                    log.info("该表没有主表，异常");
                }

                //在关联的主表中获取对应主键的定义
                DbVo mainDbvo=
                        wvo.getTableVoDomain()
                                .getColumnVoDomainList()
                                .stream()
                                .filter(x->x.getDbVo().getDbIsKey()==1)
                                .findFirst()
                                .get()
                                .getDbVo();


                JoinColumn vo = field.getAnnotation(JoinColumn.class);

                if (vo != null) {
                    db.setDbDefaultVal(null); //如果这里要实现的话，需要单独开个方法：jpa对象->class.newInstance()->反射获取字段值
                    db.setDbFieldName(vo.name());
                    String comment = vo.columnDefinition();
                    if (StringUtils.isNotBlank(comment)) {
                        db.setDbFieldTxt(comment.substring(comment.indexOf("'") + 1, comment.length() - 1));
                    }else {
                        db.setDbFieldTxt(field.getName());
                    }
                    if(field.getAnnotation(Id.class)!=null)
                        db.setDbIsKey(1);
                    else  db.setDbIsKey(0);


                    //db.setDbIsKey(vo.unique() ? 0 : 1);
                    db.setDbIsNull(vo.nullable() ? 0 : 1);
                    db.setDbLength(mainDbvo.getDbLength());
                    db.setDbPointLength(mainDbvo.getDbPointLength());
                    db.setDbType(mainDbvo.getDbType());
                    //db.setDbPointLength(mainDbvo.getDbPointLength());


                    //special设置，没有从注解上进行设置
                    db.setDbDefaultVal("");
                    db.setValidateVo(null);

                    db.setFieldName(oConvertUtils.camelName(vo.name()));

                    db.setFieldType(mainDbvo.getFieldType());

                    column.setDbVo(db);

                    //同时要更新TabelDomain中的内容
                    tableVoDomain.setEnumTableType(EnumTableType.MAINTABLE);
                    tableVoDomain.setForeignKeys(new String[]{vo.name()});
                    tableVoDomain.setOriginalForeignKeys(new String[]{oConvertUtils.camelName(vo.name())});
                }



                wvo.getTableVoDomain().getSonTabeleVoDomain().add(tableVoDomain);
            }

    @Override
    protected void setFieldDbTypeExt(Field field, DbVo db) {
        //如果columnDefinition，不是采用默认值。因为默认值就是""，如果写错了，JPA在实例化的时候，就提示了
        EnumJavaMappingDbType enumJavaMappingDbType;
        /*
                    enumJavaMappingDbType = EnumJavaMappingDbType.getBycolumnDefinition(field.getType().getSimpleName());
                    //assert 布尔表达式 ：“错误信息提示”；
                    assert enumJavaMappingDbType != null : "Column注解中字段的类型不在系统的支持范围之内，当前系统仅支持8种类型,varchar,text,blob,date,datetime,decimal,int,double";*/
        //log.info("当前正常处理的字段类型：{}，字段的名称为{}",enumJavaMappingDbType,field.getName(),enumJavaMappingDbType.getDbname());
			/*//先特殊处理一下，针对DateTime的，全部转为Date
			if(enumJavaMappingDbType.getDbname().equalsIgnoreCase("datetime")){
				db.setDbType("date");
			}*/

        //如果有Column，但是在这个上面没有columnDefinition，那么就采用默认的字段类型。但是字段类型必须在6种之内，String，Date，Decimal，Integer，Double
        Field[] fields= AnnotationUtil.getAllFields(field.getClass());
        for(Field field1:fields) {
            if (field1.getAnnotation(Id.class) != null) {
                enumJavaMappingDbType = EnumJavaMappingDbType.getByDbJavaTypeName(field1.getType().getSimpleName());
                db.setDbType(enumJavaMappingDbType.getCurrentFrameWorkNeededDbType());
                break;
            }
        }

       /* //enumJavaMappingDbType = EnumJavaMappingDbType.getByDbJavaTypeName(field.getType().getSimpleName());
        assert enumJavaMappingDbType != null : "Java中定义的字段的类型不在系统的支持范围之内，当前系统仅支持6种Java类型,String," +
                "Date,BigDecimal,Integer,Double";
*/



    }
    //}

        //return column;

}
